package day01;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

public class ActivitiDemo_03 {
    //之前代码
    @Test
    public void testDeploy() {
        //获取流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取仓库 Service
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //调用 RepositoryService 中的 API
        Deployment deploy = repositoryService.createDeployment() //创建部署对象
                .addClasspathResource("bpmn/leaveProcessTwo.bpmn20.xml")
                .deploy();//进行部署

        System.out.println("部署id" + deploy.getId());
        System.out.println("部署时间" + deploy.getDeploymentTime());
    }

    //启动流程(流程实例)
    @Test
    public void testStartProessInstance() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取运行时 RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //启动流程 (获取流程流程实例)
//        runtimeService.startProcessInstanceById();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leaveProcess");

        System.out.println("流程实例ID:" + processInstance.getId());
        System.out.println("流程实例ID:" + processInstance.getProcessInstanceId());
        System.out.println("对应部署ID:" + processInstance.getDeploymentId());
        System.out.println("对应流程定义ID:" + processInstance.getProcessDefinitionId());
        System.out.println("对应流程定义Key:" + processInstance.getProcessDefinitionKey());
        System.out.println(processInstance.getName());
    }

    //进阶代码

    //查询流程定义(查看 Activiti 中部署了哪些流程定义)
    @Test
    public void testQueryProcessDefinition() {
        //获取流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取仓库 RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //查询所有流程定义
        //若想查询指定的流程定义.那么我们使用.追加对应的条件即可
        List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery()
                .list();
        for (ProcessDefinition processDefinition : processDefinitionList) {
            System.out.println("流程定义ID:" + processDefinition.getId());
            System.out.println("流程定义Ket:" + processDefinition.getKey());
            System.out.println("流程定义名称:" + processDefinition.getName());
            System.out.println("流程定义对应的XML文件路径名:" + processDefinition.getResourceName());
            System.out.println("流程定义对应的图片文件路径名:" + processDefinition.getDiagramResourceName());
            System.out.println("流程定义对应的版本号:" + processDefinition.getVersion());
            System.out.println("流程定义对应的部署ID:" + processDefinition.getDeploymentId());
            System.out.println("*****************************************");
        }
    }

    //删除流程定义
    @Test
    public void deleteProcessDefinition() {
        //获取流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取仓库 RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //删除指定流程定义  一次部署 --> 一个流程定义  删除时需要部署id
        String deploymentId = "1";
        // 若该流程下面没有正在执行的流程实例,则可以直接删除
        //repositoryService.deleteDeployment(deploymentId);
        //若该流程下面有正在执行的流程实例,则会抛出异常  默认值为false  设置为true即可删除
        repositoryService.deleteDeployment(deploymentId, true);
    }

    //流程资源下载
    @Test
    public void downLoadFile() throws Exception {

        //获取流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取仓库 RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //获取流程定义对象
        ProcessDefinition leaveProcess = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("leaveProcess")
                .latestVersion()
                .singleResult();
        //获取 XML 文件名字
        String bpmnFileName = leaveProcess.getResourceName();
        //获取 PNG 文件名
        String pngFileName = leaveProcess.getDiagramResourceName();
        //获取 XML 文件输入流
        InputStream bpmnInputStream =
                repositoryService.getResourceAsStream(leaveProcess.getDeploymentId(), bpmnFileName);
        //获取 PNG 文件输入流
        InputStream pngInputStream =
                repositoryService.getResourceAsStream(leaveProcess.getDeploymentId(), pngFileName);
        //获取 XML 输出流
        FileOutputStream bpmnFileOutputStream = new FileOutputStream("D:/leaveProcess.bpmn");
        //获取 PNG 输出流
        FileOutputStream pngFileOutputStream = new FileOutputStream("D:/leaveProcess.png");
        //使用IO工具类
        IOUtils.copy(bpmnInputStream, bpmnFileOutputStream);
        IOUtils.copy(pngInputStream, pngFileOutputStream);
        //释放资源
        pngFileOutputStream.close();
        bpmnFileOutputStream.close();
        pngInputStream.close();
        bpmnInputStream.close();
    }

    //启动流程并绑定BusinessKey
    @Test
    public void testStart() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取仓库 RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //模拟业务表ID(BusinessKey)
        String businessKey = "8001";
        //启动流程实例
        runtimeService.startProcessInstanceByKey("leaveProcess", businessKey);
    }

    //获取BusinessKey
    @Test
    public void testQueryTaskAndBusinessKey() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //任务负责人ID
        String useId = "张三";
        //查询对应任务
        List<Task> taskList = taskService.createTaskQuery()
                .taskAssignee("张三")
                .processDefinitionKey("leaveProcess")
                .list();
        for (Task task : taskList) {
            //获取到当前任务对应的流程实例id
            String processInstanceId = task.getProcessInstanceId();
            //根据流程实例id查询对应的流程实例对象
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();
            //获取BusinessKey
            String businessKey = processInstance.getBusinessKey();
            System.out.println(businessKey);
        }
    }

    //流程定义的挂起和激活
    @Test
    public void testSuspendProcessDefinition() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //查询流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("leaveProcess")
                .latestVersion()
                .singleResult();
        //判断当前流程定义的状态
        System.out.println(processDefinition.isSuspended() ? "挂起状态" : "激活状态");
        if (processDefinition.isSuspended()){
            //挂起状态 需要激活
            repositoryService.activateProcessDefinitionById(processDefinition.getId());
            System.out.println("流程定义被激活");
        }else {
            //激活状态 需要挂起
            repositoryService.suspendProcessDefinitionById(processDefinition.getId());
            System.out.println("流程定义被挂起");

        }
    }

    //流程定义及流程实例的挂起和激活
    @Test
    public void testSuspend() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //查询流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("leaveProcess")
                .latestVersion()
                .singleResult();
        //判断当前流程定义的状态
        System.out.println(processDefinition.isSuspended() ? "挂起状态" : "激活状态");
        if (processDefinition.isSuspended()){
            //挂起状态 需要激活
            repositoryService.activateProcessDefinitionById(processDefinition.getId(),true,null);
            System.out.println("流程定义被激活");
        }else {
            //激活状态 需要挂起
            //三个参数  流程定义ID 当前流程定义对应的流程实例是否一起挂起  什么时间挂起(null 立即挂起)
            repositoryService.suspendProcessDefinitionById(processDefinition.getId(),true,null);
            System.out.println("流程定义被挂起");

        }
    }
}
